<template>
  <div>
    <el-form label-width="100px">
      <el-form-item label="SPU名称">
        <el-input placeholder="SPU名称" v-model="spuForm.spuName"></el-input>
      </el-form-item>

      <el-form-item label="品牌">
        <el-select v-model="spuForm.tmId" placeholder="请选择">
          <!-- 每一个option必须要有一个value属性 -->
          <el-option v-for="tm in trademarkList" :key="tm.id" :label="tm.tmName" :value="(tm.id as number)"> </el-option>
        </el-select>
      </el-form-item>

      <el-form-item label="SPU描述">
        <el-input type="textarea" rows="4" placeholder="SPU描述" v-model="spuForm.description"></el-input>
      </el-form-item>

      <el-form-item label="SPU图片">
        <!-- v-model:file-list值是要显示的图片数组 -->
        <!-- v-model:file-list那个图片数组 里面的图片对象 必须要有name以及url属性 -->
        <el-upload v-model:file-list="(spuImageList as UploadUserFile[])" :action="`${baseUrl}/admin/product/upload`"
          list-type="picture-card" :on-preview="handlePictureCardPreview" :on-remove="handleRemove"
          :on-success="handleSuccess">
          <el-icon>
            <Plus />
          </el-icon>
        </el-upload>
        <el-dialog v-model="dialogVisible">
          <img w-full :src="dialogImageUrl" alt="Preview Image" />
        </el-dialog>
      </el-form-item>

      <el-form-item label="销售属性">
        <el-select v-model="saleAtteIdAndName" :placeholder="`还有${unSelectSaleAttrList.length}个未选择`">
          <!-- 每一个option的value值应该是未选择销售属性的id+name 回头咱们增加spu自己的销售属性列表时需要装填他的基础销售属性id以及名字 -->
          <el-option v-for="unSelectSaleAttr in unSelectSaleAttrList" :key="unSelectSaleAttr.id"
            :label="unSelectSaleAttr.name" :value="`${unSelectSaleAttr.id}:${unSelectSaleAttr.name}`"> </el-option>
        </el-select>
        <el-button type="primary" size="default" @click="addSpuSaleAttr" :disabled="!saleAtteIdAndName">添加销售属性</el-button>
        <el-table :data="spuSaleAttrList" border>
          <el-table-column label="序号" type="index" align="center" width="80"></el-table-column>
          <el-table-column label="属性名" prop="saleAttrName"></el-table-column>
          <el-table-column label="属性值名称列表">
            <template v-slot="{ row, $index }">
              <el-tag @close="row.spuSaleAttrValueList.splice(index, 1)"
                v-for="(saleAttrValue, index) in row.spuSaleAttrValueList" :key="saleAttrValue.id" class="mx-1" closable
                :disable-transitions="false">
                {{ saleAttrValue.saleAttrValueName }}
              </el-tag>
              <!-- 先把用户输入的销售属性值名称暂存到销售属性对象身上 -->
              <el-input v-model="row.saleAttrValueName" v-if="row.isEdit" style="width: 100px;" ref="InputRef"
                class="ml-1 w-20" size="small" @keyup.enter="handleInputConfirm(row)" @blur="handleInputConfirm(row)" />
              <el-button v-else @click="toEdit(row)" class="button-new-tag ml-1" size="small">
                添加
              </el-button>
            </template>
          </el-table-column>
          <el-table-column label="操作">
            <template v-slot="{ row, $index }">
              <el-button @click="spuSaleAttrList.splice($index, 1)" type="danger" size="small" icon="ele-Delete"
                title="删除销售属性"></el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>

      <el-form-item>
        <el-button type="primary" size="default" @click="save" :disabled="!spuSaleAttrList.length">保存</el-button>
        <el-button size="default" @click="cancel">取消</el-button>
      </el-form-item>

    </el-form>

  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue"
export default defineComponent({
  name: 'SpuForm',
})
</script>

<script lang="ts" setup>
import { ref, onMounted, computed, nextTick } from 'vue'
import { Plus } from '@element-plus/icons-vue'
import { ElMessage, type UploadFile, type UploadFiles, type UploadProps, type UploadUserFile } from 'element-plus'
import type { SpuData } from '@/api/spu'
import trademarkApi, { type TrademarkData } from '@/api/trademark'
import spuApi, { type BaseSaleAttrListData, type SpuImageListData, type SpuSaleAttrListData, type SpuSaleAttrData, type ResponseData } from '@/api/spu'
import skuApi from '@/api/sku'
import { useCategoryStore } from '@/stores/category'
import { storeToRefs } from 'pinia'

const categoryStore = useCategoryStore()
const { category3Id } = storeToRefs(categoryStore)
const emit = defineEmits(['setShowState'])
// 通过接收到spu数据  修改走进来有id  添加走进来没有id  回头想判断添加走进来的还是修改修改走进来的 看id!!!
const props = defineProps<{
  spu: SpuData
}>()
// 定义一个变量 简化咱们使用props传递过来的spu数据 spuForm其实就是收集数据所使用到的那个对象
const spuForm = props.spu

// 保存初始化数据
const trademarkList = ref<TrademarkData[]>([])
const baseSaleAttrList = ref<BaseSaleAttrListData>([])
const spuImageList = ref<SpuImageListData>([])
const spuSaleAttrList = ref<SpuSaleAttrListData>([])

// 计算未选择的销售属性列表
const unSelectSaleAttrList = computed(() => {
  // 根据所有的基础销售属性列表以及spu自己的销售属性列表 进行过滤
  return baseSaleAttrList.value.filter(item => {
    // 拿到基础销售属性的名字和spu自己的每一个销售属性名字进行对比 如果一样 不要 不一样 才要
    return spuSaleAttrList.value.every(item1 => {
      return item.name !== item1.saleAttrName
    })
  })
})

// 定义获取添加spu的初始化请求函数
async function initAddData() {
  // 获取所有的品牌列表 获取所有的基础销售属性列表
  try {
    const res1 = await trademarkApi.getTrademarkList()
    trademarkList.value = res1
    const res2 = await spuApi.getBaseSaleAttrList()
    baseSaleAttrList.value = res2
  } catch (error) {
    ElMessage.error('获取添加spu的初始化请求失败')
  }
}
// 定义获取修改spu的初始化请求函数
async function initUpdateDara() {
  // 获取所有的品牌列表 获取所有的基础销售属性列表 获取spu自己的图片列表 获取spu自己的销售属性列表
  try {
    const promise1 = trademarkApi.getTrademarkList()
    const promise2 = spuApi.getBaseSaleAttrList()
    const promise3 = skuApi.getSpuImageList(spuForm.id as number)
    const promise4 = skuApi.getSpuSaleAttrList(spuForm.id as number)
    // 如果每一个promise都是成功的 Promise.all返回的promise也是成功的
    // Promise.all返回的成功promise结果就是每一个promise成功的结果所组成的一个数组
    const res = await Promise.all([promise1, promise2, promise3, promise4])
    trademarkList.value = res[0]
    baseSaleAttrList.value = res[1]
    spuImageList.value = res[2]
    spuImageList.value.forEach(item => {
      // 给每一个图片对象增加name属性和url属性 目的是为了在照片墙中显示这些图片
      item.name = item.imgName
      item.url = item.imgUrl
    })
    spuSaleAttrList.value = res[3]
  } catch (error) {
    ElMessage.error('获取修改spu的初始化请求失败')
  }
}
// 挂载发送请求获取添加或修改的初始化数据
onMounted(() => {
  if (spuForm.id) { //修改spu走进来的
    initUpdateDara()
  } else { //添加spu走进来的
    initAddData()
  }
})

// 点击取消
function cancel() {
  // 触发自定义事件 把showState数据改为1 显示SpuList组件
  emit('setShowState', 1)
}

// 引入全局变量的环境
const baseUrl = import.meta.env.VITE_API_URL
const dialogImageUrl = ref('')
const dialogVisible = ref(false)
// 对于图片的收集而言 需要捕获删除以及新增的操作 拿到最新的列表
// 删除图片执行的回调函数
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  // console.log(uploadFile, uploadFiles) uploadFile删除的那个图片数据  uploadFiles删除完成后剩下的图片列表
  spuImageList.value = uploadFiles as any
}
// 上传图片成功的回调函数
function handleSuccess(response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) {
  // console.log(response,uploadFile,uploadFiles) //uploadFiles 上传成功后最新的图片列表数据
  spuImageList.value = uploadFiles as any
}
// 预览图片的回调函数
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  // 弹出对话框 并显示正在预览的图片
  // console.log(uploadFile,'uploadFile')  uploadFile正在预览的那个图片数据
  dialogImageUrl.value = uploadFile.url!
  dialogVisible.value = true
}

// 要收集的基础销售属性的id和name
const saleAtteIdAndName = ref('')
// 点击添加销售属性
function addSpuSaleAttr() {
  // 根据刚才收集到的saleAtteIdAndName  往spuSaleAttrList数组中增加一项 
  // {
  //   baseSaleAttrId: number;
  //   saleAttrName: string;
  //   spuSaleAttrValueList: SpuSaleAttrValueListData;
  // }
  let [baseSaleAttrId, saleAttrName] = saleAtteIdAndName.value.split(':') //解构出基础销售属性的id及name
  let obj = {
    baseSaleAttrId, //基础销售属性的id
    saleAttrName, //销售属性的名字
    spuSaleAttrValueList: [], //销售属性值列表
  }
  spuSaleAttrList.value.push(obj)
  // 清除saleAtteIdAndName
  saleAtteIdAndName.value = ''
}
// 获取input组件实例
const InputRef = ref()
// 点击按钮切换到编辑模式
function toEdit(row: SpuSaleAttrData) {
  // 变编辑模式
  row.isEdit = true
  // 自动获取焦点
  nextTick(() => {
    InputRef.value.focus()
  })
}
// input回车或者失去焦点执行的回调
function handleInputConfirm(row: SpuSaleAttrData) {
  // 取到暂存销售属性值的名称
  let saleAttrValueName = row.saleAttrValueName
  // 是不是空的
  if (!row.saleAttrValueName?.trim()) {
    ElMessage.error('输入的销售属性值不能为空')
    // 清空内容 变查看模式
    row.saleAttrValueName = ''
    row.isEdit = false
    return
  }
  // 是不是重复
  let flag = row.spuSaleAttrValueList.some(item => {
    return item.saleAttrValueName === row.saleAttrValueName
  })
  if (flag) {
    ElMessage.error('输入的销售属性值不能重复')
    // 清空内容 变查看模式
    row.saleAttrValueName = ''
    row.isEdit = false
    return
  }
  // 需要往当前销售属性的销售属性值列表中增加一项 row.spuSaleAttrValueList 
  // {
  //   baseSaleAttrId: number; //这个属性值所属的那个销售属性的id
  //   saleAttrValueName: string; //销售属性值得名称
  // }
  let obj = {
    baseSaleAttrId: row.baseSaleAttrId,
    saleAttrValueName: saleAttrValueName as string
  }
  row.spuSaleAttrValueList.push(obj)
  // 清空内容 变查看模式
  row.saleAttrValueName = ''
  row.isEdit = false
}
// 保存的逻辑
async function save() {
  let spu = spuForm
  // {
  //   category3Id: '', store
  //   description: '', v-model
  //   spuName: '', v-model
  //   tmId: '', v-model
  //   spuImageList: [],
  //   spuSaleAttrList: [],
  // }
  // 整理参数
  // 1.三级分类id
  spu.category3Id = category3Id.value
  // 2.处理图片列表
  spu.spuImageList = spuImageList.value.map(item => {
    return {
      imgName: item.name, //无论是新图还是旧图都有name
      imgUrl: item.imgUrl || (item.response as ResponseData).data //旧图取imgUrl 新图response.data
    }
  })
  // 3.处理销售属性列表  销售属性中去除saleAttrValueName isEdit
  spuSaleAttrList.value.forEach(item=>{
    delete item.isEdit
    delete item.saleAttrValueName
  })
  spu.spuSaleAttrList = spuSaleAttrList.value
  // 发请求
  try {
    await spuApi.addOrUpdate(spu)
    ElMessage.success('保存成功')
    emit('setShowState', 1)
  } catch (error) {
    ElMessage.error('保存失败')
  }
}
</script>

<style scoped></style>